package com.zt.chatgpt.openai.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.zt.chatgpt.openai.model.aggregates.ChatProcessAggregate;
import com.zt.chatgpt.openai.model.aggregates.UserAccountQuotaEntity;
import com.zt.chatgpt.openai.model.entity.RuleLogicEntity;
import com.zt.chatgpt.openai.model.valobj.LogicCheckTypeVO;
import com.zt.chatgpt.openai.repository.IOpenAiRepository;
import com.zt.chatgpt.openai.service.channel.OpenAiGroupService;
import com.zt.chatgpt.openai.service.rule.factory.DefaultLogicFactory;
import com.zt.chatgpt.session.OpenAiSession;
import com.zt.chatgpt.types.common.Constants;
import com.zt.chatgpt.types.enums.OpenAiChannel;
import com.zt.chatgpt.types.exception.ChatGPTException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * @author: zt
 * @Description: 对话模型抽象类
 * @create: 2024-05-17 20:50
 */

@Slf4j
public abstract class AbstractChatService implements IChatService{

    private final Map<OpenAiChannel, OpenAiGroupService> openAiGroup = new HashMap<>();

    /**
     * 通过构造方法注入模型服务
     */
    public AbstractChatService(OpenAiGroupService chatGLMService, OpenAiGroupService chatGPTService) {
        openAiGroup.put(OpenAiChannel.CHATGLM, chatGLMService);
        openAiGroup.put(OpenAiChannel.CHATGPT, chatGPTService);
    }

    @Resource
    private IOpenAiRepository openAiRepository;


    @Override
    public ResponseBodyEmitter completions(ResponseBodyEmitter emitter, ChatProcessAggregate chatProcessAggregate) {
        try {
            // 1. 请求应答
            emitter.onCompletion(()->{
                log.info("流式请答完成，使用模型：{}",chatProcessAggregate.getModel());
            });

            emitter.onError((e)->{
                log.error("流式请答异常，使用模型：{}",chatProcessAggregate.getModel(),e);
            });

            // 2. 获取账户信息
            UserAccountQuotaEntity userAccountQuotaEntity = openAiRepository.queryUserAccount(chatProcessAggregate.getOpenId());

            // 3. 执行规则过滤
            RuleLogicEntity<ChatProcessAggregate> ruleLogicEntity = this.doCheckLogic(chatProcessAggregate,
                    userAccountQuotaEntity,
                    DefaultLogicFactory.LogicModel.ACCESS_LIMIT.getCode(),
                    DefaultLogicFactory.LogicModel.SENSITIVE_WORD.getCode(),
                    // 未获取到用户信息（访客身份）默认放行
                    null != userAccountQuotaEntity ? DefaultLogicFactory.LogicModel.ACCOUNT_STATUS.getCode() : DefaultLogicFactory.LogicModel.NULL.getCode(),
                    null != userAccountQuotaEntity ? DefaultLogicFactory.LogicModel.USER_QUOTA.getCode() : DefaultLogicFactory.LogicModel.NULL.getCode(),
                    null != userAccountQuotaEntity ? DefaultLogicFactory.LogicModel.MODEL_TYPE.getCode() : DefaultLogicFactory.LogicModel.NULL.getCode());
            if (!LogicCheckTypeVO.SUCCESS.equals(ruleLogicEntity.getType())) {
                emitter.send(ruleLogicEntity.getInfo());
                emitter.complete();
                return emitter;
            }

            // 4. 应答处理[策略模式处理]
            openAiGroup.get(chatProcessAggregate.getChannel()).doMessageResponse(ruleLogicEntity.getData(), emitter);
        } catch (Exception e) {
            throw new ChatGPTException(Constants.ResponseCode.UN_ERROR.getCode(), Constants.ResponseCode.UN_ERROR.getInfo());
        }

        // 5. 返回结果
        return emitter;
    }


    protected abstract RuleLogicEntity<ChatProcessAggregate> doCheckLogic(ChatProcessAggregate chatProcess, UserAccountQuotaEntity userAccountQuotaEntity,String... logics) throws Exception;
}
